package com.echo.service;

import com.echo.dao.ArticleDao;
import com.echo.entity.Article;
import com.echo.entity.Category;
import com.echo.exception.ArticleException;
import com.echo.util.StringUtils;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 文章服务类
 */
public class ArticleService {
    
    // 依赖DAO层
    private final ArticleDao articleDao = new ArticleDao();
    private final ArticleCategoryRelationService relationService = new ArticleCategoryRelationService();
    private final CategoryService categoryService = new CategoryService();
    private static final Logger logger = LoggerFactory.getLogger(ArticleService.class);
    
    /**
     * 发布文章
     * @param article 文章对象
     * @param categoryIds 文章分类ID列表
     * @return 文章ID
     * @throws ArticleException 文章相关异常
     * @throws SQLException SQL异常
     */
    public Integer publish(Article article, List<Integer> categoryIds) throws ArticleException, SQLException {
        // 参数校验
        validateArticleParams(article);
        
        // 设置默认值
        article.setViewCount(0);
        article.setStatus(1); // 默认为已发布状态
        article.setCreateTime(new Date());
        article.setUpdateTime(new Date());
        
        // 调用DAO层保存文章数据
        Integer articleId = articleDao.insert(article);
        if (articleId <= 0) {
            throw new ArticleException("发布文章失败！");
        }
        
        // 保存文章分类关系
        System.out.println("=== ArticleService.publish 开始保存文章分类关系 ===");
        System.out.println("文章ID: " + articleId + ", 分类ID列表: " + categoryIds);
        if (categoryIds != null && !categoryIds.isEmpty()) {
            boolean success = relationService.batchAddCategoriesToArticle(articleId, categoryIds);
            System.out.println("文章分类关系保存结果: " + success);
            if (!success) {
                logger.warn("保存文章分类关系时出现问题，文章ID: {}", articleId);
                // 不抛出异常，因为文章主体已保存成功
            }
        } else {
            System.out.println("没有提供分类ID，不保存文章分类关系");
        }
        
        return articleId;
    }
    
    /**
     * 根据ID查找文章，包含分类信息
     * @param id 文章ID
     * @return 文章对象（包含分类信息），如果不存在返回null
     */
    public Article findById(Integer id) {
        try {
            Article article = articleDao.findById(id);
            if (article != null) {
                // 加载文章的分类信息
                List<Integer> categoryIds = relationService.getArticleCategoryIds(id);
                List<Category> categories = new ArrayList<>();
                for (Integer categoryId : categoryIds) {
                    Category category = categoryService.getCategoryById(categoryId);
                    if (category != null) {
                        categories.add(category);
                    }
                }
                article.setCategories(categories);
            }
            return article;
        } catch (Exception e) {
            logger.error("查找文章失败: id = {}", id, e);
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 查询所有文章，按创建时间倒序排序
     * @return 文章列表（永远不会返回null）
     */
    public List<Article> findAllOrderByCreateTimeDesc() {
        try {
            return articleDao.findAllOrderByCreateTimeDesc();
        } catch (SQLException e) {
            e.printStackTrace();
            return new ArrayList<>(); // 发生异常时返回空列表，而不是null
        }
    }
    
    /**
     * 根据作者用户名查询文章列表（按创建时间倒序）
     * @param authorUsername 作者用户名
     * @return 文章列表
     */
    public List<Article> findByAuthorUsername(String authorUsername) {
        try {
            return articleDao.findByAuthorUsername(authorUsername);
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 根据分类ID查询文章列表
     * @param categoryId 分类ID
     * @return 文章列表
     */
    public List<Article> findByCategoryId(Integer categoryId) {
        try {
            // 获取分类下的所有文章ID
            List<Integer> articleIds = relationService.getCategoryArticleIds(categoryId);
            
            if (articleIds.isEmpty()) {
                return new ArrayList<>();
            }
            
            // 根据文章ID列表查询文章
            List<Article> articles = new ArrayList<>();
            for (Integer articleId : articleIds) {
                Article article = articleDao.findById(articleId);
                if (article != null && article.getStatus() == 1) { // 只显示已发布的文章
                    articles.add(article);
                }
            }
            
            // 按创建时间倒序排序
            articles.sort((a1, a2) -> a2.getCreateTime().compareTo(a1.getCreateTime()));
            
            return articles;
        } catch (SQLException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
    
    /**
     * 验证文章参数
     * @param article 文章对象
     * @throws ArticleException 文章相关异常
     */
    private void validateArticleParams(Article article) throws ArticleException {
        if (article == null) {
            throw new ArticleException("文章对象不能为空！");
        }
        if (StringUtils.isEmpty(article.getTitle())) {
            throw ArticleException.TITLE_EMPTY;
        }
        if (article.getTitle().length() > 255) {
            throw ArticleException.TITLE_TOO_LONG;
        }
        if (StringUtils.isEmpty(article.getContent())) {
            throw ArticleException.CONTENT_EMPTY;
        }
        if (StringUtils.isEmpty(article.getAuthorUsername())) {
            throw new ArticleException("作者名称不能为空！");
        }
    }
    
    /**
     * 更新文章
     * @param article 文章对象
     * @throws ArticleException 文章相关异常
     * @throws SQLException SQL异常
     */
    public void update(Article article) throws ArticleException, SQLException {
        System.out.println("ArticleService: 开始更新文章，ID: " + article.getId() + ", 标题: " + article.getTitle());
        
        // 参数校验
        validateArticleParams(article);
        if (article.getId() == null) {
            throw new ArticleException("文章ID不能为空！");
        }
        
        // 更新时间
        article.setUpdateTime(new Date());
        System.out.println("ArticleService: 参数校验通过，准备调用DAO更新数据库");
        
        // 调用DAO层更新数据
        int rows = articleDao.update(article);
        System.out.println("ArticleService: DAO返回影响行数: " + rows);
        
        if (rows <= 0) {
            throw new ArticleException("更新文章失败！");
        }
        
        System.out.println("ArticleService: 文章更新成功");
    }
    
    /**
     * 删除文章
     * @param id 文章ID
     * @throws ArticleException 文章相关异常
     * @throws SQLException SQL异常
     */
    
    /**
     * 增加文章阅读量（+1）
     * @param id 文章ID
     * @return 是否成功
     */
    public boolean incrementViewCount(Integer id) {
        try {
            int rows = articleDao.incrementViewCount(id);
            return rows > 0;
        } catch (SQLException e) {
            logger.error("增加文章阅读量失败: id = {}", id, e);
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * 删除文章
     * @param id 文章ID
     * @throws ArticleException 文章相关异常
     * @throws SQLException SQL异常
     */
    public void delete(Integer id) throws ArticleException, SQLException {
        if (id == null) {
            throw new ArticleException("文章ID不能为空！");
        }
        
        // 调用DAO层删除数据
        int rows = articleDao.delete(id);
        if (rows <= 0) {
            throw new ArticleException("删除文章失败！");
        }
    }
}